from django.db import models
from base import *
from object_models import *
from resource_models import *

__all__ = ["REPRESENTATION_TYPES", "Protocol", "CompositeProtocol", "ChildProtocol", "ClusterFinder",
           "Simulator", "Physics", "InputParameter", "ParameterGroup", "ParameterGroupMember",
           "RepresentationObjectType", "Algorithm"]

REPRESENTATION_TYPES = (('point particle',
                         'Represents the case where point particles are used to represent the simulated world.'),
                        ('SPH particle',
                         'Represents the case where extended particles with hydro properties are used to represent the simulated world in an SPH simulation.'),
                        ('extended particle',
                         'Represents the case where extended particles are used to represent the simulated world.'),
                        ('simple mesh cell',
                         'Represents the case where simple, non-structured/subdivided mesh cells are used to represent the simulated world in a regular grid.'),
                        ('hierarchical mesh cell',
                         'Represents the case where mesh cells that may be hierarchically subdivided are used to represent the simulated world in an adaptive mesh refinemenet simulation.'),
                        ('model astro object',
                         'Represents the case where mock astronomical objects with their "physical" properties are used to represent the simulated world. Mainly found in results of post-processing. Examples are dark matter halos as the result of a cluster finder, synthetic galaxies as the result of semi-analytical simulations or halo occupation distributions algorithms.'),
                        ('custom',
                         'Represents the case wherecustom objects, for which there is no existing term available in this enumeration, are used to represent the simulated world.'))

class Protocol(Resource):
    _collection_sets = []
    element_name = 'aProtocol'
    code = models.CharField(max_length=1024)
    version = models.CharField(max_length=1024)

class InputParameter(Field):
    _collection_sets = []
    protocol = models.ForeignKey(Protocol)
    label = models.CharField(max_length=1024, blank=True)
    _container_field = "protocol_id"
    Protocol._collection_sets.append('inputparameter_set')
    
class ParameterGroup(MetadataObject):
    _collection_sets = []
    protocol = models.ForeignKey(Protocol)
    name = models.CharField(max_length=256)
    description = models.TextField(blank=True)
    _container_field = "protocal_id"
    Protocol._collection_sets.append('parametergroup_set')

class ParameterGroupMember(MetadataObject):
    _collection_sets = []
    parametergroup = models.ForeignKey(ParameterGroup)
    parameter = models.ForeignKey(InputParameter)
    _container_field = "parametergroup_id"
    ParameterGroup._collection_sets.append('parametergroupmember_set')

class Algorithm(MetadataObject):
    _collection_sets = []
    protocol = models.ForeignKey(Protocol)
    name = models.CharField(max_length=256)
    description = models.TextField(blank=True)
    label = models.CharField(max_length=256, blank=True)
    _container_field = "protocol_id"
    Protocol._collection_sets.append('algorithm_set')

class RepresentationObjectType(ObjectType):
    _collection_sets = []
    protocol = models.ForeignKey(Protocol)
    type = models.CharField(max_length=256,
                            choices=REPRESENTATION_TYPES, default='custom')
    label = models.CharField(max_length=1024, blank=True)
    _container_field = "protocol_id"
    Protocol._collection_sets.append('representationobjecttype_set')

class Simulator(Protocol):
    _collection_sets = []
    element_name = 'aSimulator'

class Physics(MetadataObject):
    _collection_sets = []
    simulator = models.ForeignKey(Simulator)
    name = models.CharField(max_length=256, blank=True)
    description = models.TextField(blank=True)
    texform = models.TextField(blank=True)
    physicslabel = models.CharField(max_length=256, blank=True)
    _container_field = "simulator_id"
    Simulator._collection_sets.append('physics_set')

class ClusterFinder(Protocol):
    _collection_sets = []
    element_name = 'aClusterFinder'

class CompositeProtocol(Protocol):
    _collection_sets = []
    element_name = 'aCompositeProtocol'

class ChildProtocol(MetadataObject):
    _collection_sets = []
    compositeprotocol = models.ForeignKey(CompositeProtocol,
                                          related_name='childprotocol_related')
    protocol = models.ForeignKey(Protocol)
    _container_field = "compositeprotocol_id"
    CompositeProtocol._collection_sets.append('childprotocol_related')
